define('apps/common/PriceSuggestion', ['core/jQuery', 'core/InputListener', 'core/List', 'core/Caret'], function(require) {

    var $ = require('core/jQuery'),
        InputListener = require('core/InputListener'),
        Caret = require('core/Caret'),
        List = require('core/List'),

        TPL = {
            'listCnt' : '<div class="ui_list list_price">\
                            <ul class="ui_list_bd">\
                                <li class="_j_listitem" data-pu="￥"><a href="#"><span class="r">人民币</span>￥</a></li>\
                                <li class="_j_listitem" data-pu="$"><a href="#"><span class="r">美元</span>$</a></li>\
                                <li class="_j_listitem" data-pu="HK$"><a href="#"><span class="r">港币</span>HK$</a></li>\
                                <li class="_j_listitem" data-pu="JP￥"><a href="#"><span class="r">日元</span>JP￥</a></li>\
                                <li class="_j_listitem" data-pu="₩"><a href="#"><span class="r">韩币</span>₩</a></li>\
                                <li class="_j_listitem" data-pu="NT$"><a href="#"><span class="r">新台币</span>NT$</a></li>\
                                <li class="_j_listitem" data-pu="€"><a href="#"><span class="r">欧元</span>€</a></li>\
                                <li class="_j_listitem" data-pu="£"><a href="#"><span class="r">英镑</span>£</a></li>\
                            </ul>\
                            <div class="price_tip">货币符紧跟数字，可被识别为价格</div>\
                        </div>'
        };

    function PriceSuggestion(opts) {
        this.area = null;
        this.source = 'web'; // 使用源（默认：web，其他：plug）
        this.focusShow = false;

        K.mix(this, opts);
        this.area = $(this.area);

        this.init();
    }

    PriceSuggestion.prototype = {
        'init' : function() {
            this.initInputListener();
            this.bindEvents();
        },

        'initInputListener' : function() {
            this.priceListener = new InputListener({
                'area' : this.area,
                'listenLetter' : ['$', '￥', '£', '€', '¥', '₩']
            });

            this.priceListener.on('hit', $.proxy(this.hitPrice, this));
            this.priceListener.on('unhit', $.proxy(this.unHitPrice, this));
        },

        'bindEvents' : function() {
            var area = this.area;

            // 监听keyup
            area.keyup($.proxy(this.keyupListener, this));

            // blur隐藏
            area.blur($.proxy(function() {
                if(this.list && !this.list.mouseon) {
                    this.hide();
                }
            }, this));

            // 监听keydown
            if ($.browser.opera) { // opera下keydown事件不能被阻止
                area.keypress($.proxy(this.keydownListener, this));
            } else {
                area.keydown($.proxy(this.keydownListener, this));
            }
            
            // 如果要focus即出现，则绑定focus事件
            if(this.focusShow) {
            	area.focus($.proxy(function() {
            		var areaOffset = area.offset();
            		if(area.val() === '') {
            			this.hitPrice({
            				'data': {
	            				'position' : 0,
	            				'offset' : {
	            					'top' : areaOffset.top + area.outerHeight(),
	            					'left' : areaOffset.left
	            				},
	            				'letter' : '',
	            				'caretStart' : 0
	            			}
            			});
            		}
            	}, this));
            }
        },

        'hitPrice' : function(args) {
            var data = args.data;
            this.targetPosition = data.position;
            this.targetOffset = data.offset;
            this.targetLetter = data.letter;
            this.caretStart = data.caretStart;
            this.showList();
            K.fire('giflog', {'key':'jsstat', 'params':{'type' : 'pic_price', 'source':this.source}, 'withUid':true});
        },

        'unHitPrice' : function() {
            this.hide();
        },

        'showList' : function() {
            if(!this.list) {
                this.initList();
            }
            this.list.show();
        },


        /**
         * 个性化定制suggest下拉框
         */
        'initList' : function() {
            var _this = this;
            this.list = new List({
                'trigger' : this.area,

                'createContainer' : function() {
                    this.container = $(TPL.listCnt).appendTo('body');
                },

                'getValue' : function() {
                    return this.container.find('.'+this.itemHoverClass).data('pu');
                },

                'updateList' : function() {
                    this.container.find(this.itemSelector).removeClass(this.itemHoverClass);
                    this.container.find(this.itemSelector).first().addClass(this.itemHoverClass);
                    this.container.find(this.itemSelector).last().addClass('last');
                    _this.setListPosition();
                }
            });
            this.list.on('outputvalue', $.proxy(this.receiveValue, this));
        },

        /**
         * 主要是将一些@下拉框使用的键盘事件的默认行为阻止掉
         */
        'keydownListener' : function(ev) {
            var keyCode = ev.keyCode;
            if(this.priceListener.hit) { // 用来在suggest list显示的情况下阻止默认上、下、enter键盘事件
                if(keyCode === 38 || keyCode === 40 || keyCode === 13 || keyCode === 27) {
                    ev.preventDefault();
                }
            }
        },

        'keyupListener' : function(ev) {
            var keyCode = ev.keyCode;
            if(this.priceListener.hit && keyCode === 27) { // esc 退出处理
                this.hide();
                ev.preventDefault();
                ev.stopPropagation();
            }
        },

        'setListPosition' : function() {
            this.list.container.css(this.targetOffset);
        },

        'receiveValue' : function(args) {
            var areaVal = this.area.val(),
                caretPosition = this.caretStart,
                beforeTargetString = areaVal.slice(0, this.targetPosition),
                afterCaretString = areaVal.slice(caretPosition),
                beforeCaretString = beforeTargetString + args.data,
                newCaretPosition = beforeCaretString.length;

            this.area.val(beforeCaretString + afterCaretString);
            //this.currVal = beforeCaretString + afterCaretString;
            //this.atNames.push(args.data);
            //this.updateHighLighter();
            this.list.hide();
            this.priceListener.selected = true;
            this.priceListener.keyString = beforeCaretString;
            Caret.setCaretPosition(this.area, newCaretPosition, newCaretPosition);
        },

        'hide' : function() {
            if(this.list && this.list.container.is(':visible')) {
                this.list.hide();
            }
        }

    };

    return PriceSuggestion;
});
